package com.cashmama.market.api.domain.service;

import com.alibaba.fastjson.JSONObject;
import com.amazonaws.services.dynamodbv2.xspec.S;
import com.cashmama.market.api.domain.enums.CategoryTypeDescEnum;
import com.cashmama.market.api.domain.enums.CollisionResultEnm;
import com.cashmama.market.api.domain.handler.ConfigHandler;
import com.cashmama.market.api.domain.handler.order.OrdersHandler;
import com.cashmama.market.api.domain.vo.RequestLocalInfo;
import com.cashmama.market.api.domain.vo.home.*;
import com.cashmama.market.api.domain.vo.openapi.OpenApiResponse;
import com.cashmama.market.api.domain.vo.openapi.request.CollisionDataRequest;
import com.cashmama.market.api.domain.vo.openapi.request.PullAmountAndTermRequest;
import com.cashmama.market.api.domain.vo.openapi.response.CollisionDataVO;
import com.cashmama.market.api.domain.vo.openapi.response.PullAmountTermVO;
import com.cashmama.market.api.domain.vo.order.OrderFieldDetail;
import com.cashmama.market.api.domain.vo.product.BorrowCashPeriodVO;
import com.cashmama.market.api.domain.vo.product.BorrowCashVO;
import com.cashmama.market.api.domain.vo.product.ProductDetailVO;
import com.cashmama.market.api.infras.config.ApolloConfigUtil;
import com.cashmama.market.api.infras.consts.RedisKeyConsts;
import com.cashmama.market.api.infras.enums.AuditProductEnum;
import com.cashmama.market.api.infras.enums.BasicErrorCodeEnum;
import com.cashmama.market.api.infras.enums.JumpRouterEnum;
import com.cashmama.market.api.infras.enums.PackageNameEnum;
import com.cashmama.market.api.infras.enums.order.OpenOrderStatusEnum;
import com.cashmama.market.api.infras.exception.ApplicationException;
import com.cashmama.market.api.infras.utils.DateUtil;
import com.cashmama.market.api.infras.utils.DecimalUtils;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.MD5;
import com.fqgj.xjd.user.client.UserInfoService;
import com.fqgj.xjd.user.client.enums.FrozenCodeEnum;
import com.fqgj.xjd.user.client.request.UserOpenBlackListRequest;
import com.fqgj.xjd.user.client.response.UserInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.jsoniter.JsonIterator;
import com.jsoniter.any.Any;
import com.jsoniter.output.JsonStream;
import com.qianli.cashmama.product.facade.ProductFacade;
import com.qianli.cashmama.product.facade.enums.CategoryTypeEnum;
import com.qianli.cashmama.product.facade.enums.PaybackPeriodUnitEnum;
import com.qianli.cashmama.product.facade.result.Product;
import com.qianli.cashmama.product.facade.result.ProductCategory;
import com.qianli.cashmama.trade.client.offer.QuoteQueryService;
import com.qianli.cashmama.trade.client.offer.response.OfferResponse;
import com.qianli.cashmama.trade.client.vo.TradeVO;
import com.qianli.cashmama.trade.common.enums.TradeStatusEnum;
import com.qianli.user.enums.UserAuthStatusEnum;
import com.qianli.user.ro.auth.UserAuthStatusRO;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: market-api
 * @description 产品信息
 * @author: frank
 * @create: 2019-12-23 14:06
 **/
@Service
public class ProductService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ProductService.class);
    @Autowired
    private ApiTradeService apiTradeService;
    @Autowired
    private ProductFacade productFacade;
    @Autowired
    private ApolloConfigUtil apolloConfigUtil;
    @Autowired
    private ApiUserCenterService apiUserCenterService;
    @Autowired
    private ApiUserService apiUserService;
    @Autowired
    private QuoteQueryService quoteQueryService;
    @Autowired
    private OrdersHandler ordersHandler;
    @Autowired
    private ConfigHandler configHandler;
    @Autowired
    private UserEventTrackService userEventTrackService;
    @Autowired
    private ApiProductService apiProductService;
    @Autowired
    private RedisClient redisClient;

//    [CashMall] limited time benefits for borrowing again today, up to 35000 Rs. 90% pass rate. click https://bit.ly/2ZwHWX4 . Vasuki Information

    @Autowired
    private UserInfoService userInfoService;

    public HomeVO getHomeInfo() {

        LOGGER.info("== home 1==");
        String userCode = RequestLocalInfo.getCurrentUser() == null
                ? null : RequestLocalInfo.getCurrentUser().getUserCode();
        List<CategoryVO> categoryList = this.getCategoryList(userCode);

        LOGGER.info("== home 2==");
        //1、广告位
        List<AdvertisementVO> ads = this.getAdvertises();
        LOGGER.info("== home 3==");
        //2、推荐位
        List<CategoryVO> recommendationList = this.getRecommendCategories(categoryList, CategoryTypeEnum.RECOMMEND.getCode());
        LOGGER.info("== home 4==");
        //3、更多推荐
        List<CategoryVO> moreRecommendationList = this.getRecommendCategories(categoryList, CategoryTypeEnum.COMMON.getCode());
        LOGGER.info("== home 5==");
        moreRecommendationList = moreRecommendationList.stream().sorted(Comparator.comparing(CategoryVO::getPermitApply, (o1, o2) -> {
            if (o1 ^ o2) {
                return o1 ? -1 : 1;
            } else {
                return 0;
            }
        }).thenComparing(CategoryVO::getOrderStatus).thenComparing(CategoryVO::getSort)).collect(Collectors.toList());
        return new HomeVO(new HomeNoticeVO(), recommendationList, ads, moreRecommendationList, configHandler.getPermissionsInfoFromString(""));
    }

    private List<AdvertisementVO> getAdvertises() {
        List<AdvertisementVO> advertisements = Lists.newArrayList();
        try {
            if (StringUtils.isEmpty(apolloConfigUtil.getAdvertises())) {
                return advertisements;
            }
            advertisements = JSONObject.parseArray(apolloConfigUtil.getAdvertises(), AdvertisementVO.class);
        } catch (Exception e) {
            LOGGER.error("转换广告位配置出错，e:" + e);
        }
        return advertisements;
    }

    private HomeNoticeVO getHomeNotice() {
        HomeNoticeVO homeNotice = new HomeNoticeVO();
        try {

            String homeNotice1 = apolloConfigUtil.getHomeNotice();
            if (StringUtils.isEmpty(homeNotice1)) {
                return homeNotice;
            }
            homeNotice = JSONObject.parseObject(homeNotice1, HomeNoticeVO.class);
        } catch (Exception e) {
            LOGGER.error("转换公告栏配置出错，e:" + e);
        }
        return homeNotice;
    }

    /**
     * 根据type筛选机构类型
     *
     * @param productCategories
     * @param type
     * @return
     */
    private List<CategoryVO> getRecommendCategories(List<CategoryVO> productCategories, Integer type) {
        if (CollectionUtils.isEmpty(productCategories)) {
            return Lists.newArrayList();
        }
        return productCategories.stream().filter(s -> s.getCategoryType().equals(type)).collect(Collectors.toList());
    }

    /**
     * 根据userCode获取机构产品列表
     *
     * @param userCode
     * @return
     */
    public List<CategoryVO> getCategoryList(String userCode) {

        String packageName = RequestLocalInfo.getRequestBasicInfo().getPackageName();
        List<ProductCategory> productCategories22 = apiProductService.getAllActiveProductCategoryList();
        List<TradeVO> tradeInfos = Lists.newArrayList();
        if (StringUtils.isNotBlank(userCode)) {
            tradeInfos = apiTradeService.getTradeInfoListByUserCode(userCode);
        }

        if (CollectionUtils.isEmpty(productCategories22)) {
            throw new ApplicationException("no more products!");
        }

        List<ProductCategory> productCategories = new ArrayList<>();
        boolean isWhiteUser = userCode == null ? false : apolloConfigUtil.getWhiteUserCodes().contains(userCode);
        productCategories22.forEach(ct -> {
            boolean isWhiteProduct = apolloConfigUtil.getWhiteProducts().contains(ct.getCode());
            LOGGER.info("=== 白名单列表 ===,userCode:{},isWhiteProduct:{},isWhiteUser:{},productCode:{}", userCode, isWhiteProduct, isWhiteUser, ct.getCode());
            if (isWhiteProduct) {
                if (isWhiteUser) {
                    productCategories.add(ct);
                }
            } else {
                productCategories.add(ct);
            }
        });
        ArrayList<ProductCategory> productCategories1 = Lists.newArrayList();
        productCategories.forEach(productCategory -> {
            LOGGER.info("版本比较,v1:{},v2:{}", RequestLocalInfo.getRequestBasicInfo().getVersionCode(), apolloConfigUtil.getDefaultOnlineVersionCode());
//            if (RequestLocalInfo.getRequestBasicInfo().getVersionCode() == apolloConfigUtil.getDefaultOnlineVersionCode()) {
//                if (apolloConfigUtil.getDefaultOnlineAppList(productCategory.getMerchantCode())) {
//                    productCategories1.add(productCategory);
//                }
//            } else {
//                if (!apolloConfigUtil.getDefaultOnlineAppList(productCategory.getMerchantCode())) {
//                    productCategories1.add(productCategory);
//                }
//            }
            if ("com.vayloan.app".equals(packageName) || "in.meraloan.app".equals(packageName) || "in.cashzone.app".equals(packageName)) {
                LOGGER.info("== com.vayloan.app ==,getTrueCategories:{}", apolloConfigUtil.getTrueCategories());
                if (!apolloConfigUtil.getTrueCategories().contains(productCategory.getCode())) {
                    productCategories1.add(productCategory);
                }
            } else {


                String hideCategoriesInHomeList = apolloConfigUtil.getHideCategoriesInHomeList();
                LOGGER.info("== productCategories1 ==,size:{}", productCategories1.size());

                if (hideCategoriesInHomeList.contains(productCategory.getCode())) {
                    return;
                }

                boolean gpCheckByPackage = apolloConfigUtil.getGpCheckByPackage();
                if (gpCheckByPackage) {
                    if ("com.kly.cm.mall".equals(packageName)) {
                        if (userCode == null) {
                            if (apolloConfigUtil.getHomeListHideProductCategory(productCategory.getCode())) {
                                return;
                            }
                        } else {
                            String mobile = userInfoService.getUserInfoByUserCode(userCode).getData().getUser().getMobile();
                            if (mobile.equals("8050843255") && apolloConfigUtil.getHomeListHideProductCategory(productCategory.getCode())) {
                                return;
                            }
                        }
                        if (productCategory.getForGp() == 1 || productCategory.getForGp() == 3) {
                            productCategories1.add(productCategory);
                        }
                    } else {
                        if (productCategory.getForGp() != 1) {
                            productCategories1.add(productCategory);
                        }
                    }
                } else {
                    boolean isGpVersion = RequestLocalInfo.getRequestBasicInfo().getVersionCode() >= apolloConfigUtil.getDefaultOnlineVersionCode();
                    if (isGpVersion) {
                        if (productCategory.getForGp() == 1 || productCategory.getForGp() == 3) {
                            productCategories1.add(productCategory);
                        }
                    } else {
                        if (productCategory.getForGp() != 1) {
                            productCategories1.add(productCategory);
                        }
                    }
                }
            }
        });

        List<CategoryVO> categoryList = Lists.newArrayList();
        List<TradeVO> finalTradeInfos = tradeInfos;
        productCategories1.forEach(productCategory -> {
            Map collisionMap = Maps.newHashMap();
            collisionMap.put(productCategory.getCode(), true);
            CategoryVO categoryVO = new CategoryVO();
            categoryVO.setCategoryApplicationRatio(productCategory.getApplyRate());
            categoryVO.setMerchantCode(productCategory.getMerchantCode());
            categoryVO.setCategoryTypeDesc(CategoryTypeDescEnum.getCategoryTypeDescEnumByType(productCategory.getCategoryType()).getName());
            categoryVO.setCategoryType(productCategory.getCategoryType());
            categoryVO.setCategoryCode(productCategory.getCode());
            categoryVO.setCategoryName(productCategory.getName());
            categoryVO.setCategoryLogo(productCategory.getLogo());
            categoryVO.setButtonJumpUrl(JumpRouterEnum.PRODUCT_DETAIL.getJumpUrl() + "?categoryCode=" + productCategory.getCode() + "&merchantCode=" + productCategory.getMerchantCode());
//            categoryVO.setCategoryStatusOnline();
            categoryVO.setCategoryDesc(productCategory.getCategoryDesc());
            categoryVO.setCategoryRange("₹" + DecimalUtils.formatDecimal(new BigDecimal(productCategory.getMoneyFloor())) + "-" + DecimalUtils.formatDecimal(new BigDecimal(productCategory.getMoneyUpper())));
            categoryVO.setButtonName("Get Now");
            categoryVO.setSort(productCategory.getSort());
            categoryVO.setOrderStatus(0);
            if (CollectionUtils.isNotEmpty(finalTradeInfos)) {
                finalTradeInfos.forEach(tradeInfoRO -> {
                    boolean completed = tradeInfoRO.getTradeStatus().equals(TradeStatusEnum.EARLY_REPAYMENT) ||
                            tradeInfoRO.getTradeStatus().equals(TradeStatusEnum.NORMAL_REPAYMENT) ||
                            tradeInfoRO.getTradeStatus().equals(TradeStatusEnum.OVERDUE_REPAYMENT) ||
                            tradeInfoRO.getTradeStatus().equals(TradeStatusEnum.AUDIT_REJECT) ||
                            tradeInfoRO.getTradeStatus().equals(TradeStatusEnum.MANUAL_CLOSED);
                    if (!completed && productCategory.getMerchantCode().equalsIgnoreCase(tradeInfoRO.getMerchantCode())) {
                        categoryVO.setTradeNo(tradeInfoRO.getTradeNo());
                        categoryVO.setOrderStatus(tradeInfoRO.getTradeStatus().getStatus());
                        categoryVO.setButtonName(OpenOrderStatusEnum.getByCode(tradeInfoRO.getTradeStatus().getStatus()).getDesc());
                        categoryVO.setButtonJumpUrl(JumpRouterEnum.ORDER_DETAIL.getJumpUrl() + "?tradeNo=" + tradeInfoRO.getTradeNo() + "&merchantCode=" + productCategory.getMerchantCode());
                        collisionMap.put(productCategory.getCode(), false);
                    }
                });
            }
            boolean quotaFull = false;
            if (StringUtils.isNotBlank(userCode) && (Boolean) collisionMap.get(productCategory.getCode())) {
                String mobile = RequestLocalInfo.getCurrentUser().getMobile();
                quotaFull = this.currentMerchantQuotaFull(userCode, mobile, productCategory);

            }
//            if (apolloConfigUtil.getFullProductCategory().contains(productCategory.getCode())) {
//                quotaFull = true;
//            }

            //全部 1 新客 2 老客 3 全部 4 停止放款
            Integer lendingUserType = 3;

            //0 没有 1热品 2 新品
            Integer promotionTagType = 0;

            Integer jumpType = 0;

            String jumpUrl2 = JumpRouterEnum.PRODUCT_DETAIL.getJumpUrl() + "?categoryCode=" + productCategory.getCode() + "&merchantCode=" + productCategory.getMerchantCode();

            //是否已满 0 未满 1 满
            Integer fullType = 0;

            String extraInfo = productCategory.getExtraInfo();
            if (!com.fqgj.common.utils.StringUtils.isEmpty(extraInfo)) {
                Any deserialize = JsonIterator.deserialize(extraInfo);
                Any lendingUserType1 = deserialize.get("lendingUserType");
                if (lendingUserType1 != null) {
                    lendingUserType = lendingUserType1.toInt();
                }

                Any promotionTagType1 = deserialize.get("promotionTagType");
                if (promotionTagType1 != null) {
                    promotionTagType = promotionTagType1.toInt();
                }
                Any fullType1 = deserialize.get("fullType");
                if (fullType1 != null) {
                    fullType = fullType1.toInt();
                }

                Any jumpType1 = deserialize.get("jumpType");
                if (jumpType1 != null) {
                    jumpType = jumpType1.toInt();
                }

                Any jumpUrl1 = deserialize.get("jumpUrl");
                if (jumpUrl1 != null) {
                    jumpUrl2 = jumpUrl1.toString();
                }
            }

            if (fullType == 1) {
                quotaFull = true;
            }

            categoryVO.setCategoryStatusOnline(promotionTagType);
            if (quotaFull) {
                categoryVO.setPermitApply(false);
                categoryVO.setButtonName("FULL TODAY");
                categoryVO.setCategoryApplicationRatio(100);
            }

            categoryVO.setJumpType(jumpType);
            if (jumpType == 1) {
                categoryVO.setButtonJumpUrl("URL/External/" + jumpUrl2);
                categoryVO.setButtonName("google play");
            }

//            if ("SmartLoan".equals(productCategory.getCode())) {
//                categoryVO.setButtonJumpUrl("URL/External/https://bit.ly/3moSsIz");
//                categoryVO.setButtonName("google play");
//            } else if ("CashBean".equals(productCategory.getCode())) {
//                categoryVO.setButtonJumpUrl("URL/jumpgoogle?url=com.loan.cash.credit.easy.dhan.quick.udhaar.lend.game.jaldi.paisa.borrow.rupee.play.kredit");
//                categoryVO.setButtonName("google play");
//            } else {
//                categoryVO.setButtonJumpUrl(JumpRouterEnum.PRODUCT_DETAIL.getJumpUrl() + "?categoryCode=" + productCategory.getCode() + "&merchantCode=" + productCategory.getMerchantCode());
//            }
            categoryList.add(categoryVO);
        });
        return categoryList;
    }

    public boolean isUserReachMaxApplyLimit(String userCode) {
        LOGGER.info("== 查询用户的订单情况 ==");
        List<TradeVO> tradeListByUserCode = apiTradeService.getTradeListByUserCode(userCode);
        if (CollectionUtils.isEmpty(tradeListByUserCode)) {
            LOGGER.info("== 查询用户的订单情况 == 为空");
            return false;
        }

        LOGGER.info("== 查询用户的订单情况 == size:{},max:{}", tradeListByUserCode.size(), apolloConfigUtil.getUserMaxApplyLimit());
        int num = 0;
        for (TradeVO tradeVO : tradeListByUserCode) {
            LOGGER.info("== 查询用户的订单情况 == status:{}", tradeVO.getTradeStatus().getStatus());
            if (!tradeVO.getTradeStatus().equals(TradeStatusEnum.AUDIT_REJECT)
                    && !tradeVO.getTradeStatus().equals(TradeStatusEnum.NORMAL_REPAYMENT)
                    && !tradeVO.getTradeStatus().equals(TradeStatusEnum.EARLY_REPAYMENT)
                    && !tradeVO.getTradeStatus().equals(TradeStatusEnum.OVERDUE_REPAYMENT)
                    && !tradeVO.getTradeStatus().equals(TradeStatusEnum.MANUAL_CLOSED)
            ) {
                LOGGER.info("== 查询用户的订单情况+++ == status:{}", tradeVO.getTradeStatus().getStatus());
                num++;
            }
        }


        return num > apolloConfigUtil.getUserMaxApplyLimit();


    }

    /**
     * 判断机构是否可以申请
     * 撞库结果缓存到第二天凌晨零点
     *
     * @param mobile
     * @param productCategory
     * @return
     */
    public boolean currentMerchantQuotaFull(String userCode, String mobile, ProductCategory productCategory) {

        if (!apolloConfigUtil.getMerchantUserCheckSwitch()) {
            return false;
        }

        String packageName = RequestLocalInfo.getRequestBasicInfo().getPackageName();
        boolean notExceedDailyLimitNum = true;//未超过当日订单数限制
        boolean collisionPass = true;//撞库通过
        Boolean quotaFull = false;

        Long newUserOrderCounts = redisClient.getNumber(RedisKeyConsts.NEW_USER_ORDERS_NUMBER, productCategory.getMerchantCode(), DateUtil.getDate("yyyy-MM-dd"));
        if (newUserOrderCounts != null
                && new BigDecimal(newUserOrderCounts).compareTo(new BigDecimal(productCategory.getDailyApplyLimit())) >= 0) {
            notExceedDailyLimitNum = false;
            LOGGER.info("=== 产品新客申请已满 productCategory:{}, newUserOrderCounts:{}===", JSONObject.toJSONString(newUserOrderCounts), newUserOrderCounts);
        }
        if (!notExceedDailyLimitNum) {
            return true;
        }

        //贷超冷冻
        Boolean isFrozen = apiUserCenterService.checkUserFreezeByFrozenCodeEnum(userCode, productCategory.getCode(), FrozenCodeEnum.BORROW_REJECT);
        LOGGER.info("== 冷冻判断 ==,isFrozen:{}", isFrozen);
        if (isFrozen) {
            return true;
        }

//        if (redisClient.get(RedisKeyConsts.COLLISION_DATA_KEY, mobile, productCategory.getMerchantCode()) == null || !apolloConfigUtil.userCheckUserResultCache()) {
            Response<UserInfo> userInfoByUserCode = userInfoService.getUserInfoByUserCode(userCode);
            String md5Mobile = MD5.md5(mobile);
            String aadhaarNo = userInfoByUserCode.getData().getUser().getIdentityNo();
            if (!StringUtils.isEmpty(aadhaarNo)) {
                CollisionDataRequest collisionDataRequest = new CollisionDataRequest()
                        .setUserName(userInfoByUserCode.getData().getUser().getName())
                        .setProductCode(productCategory.getCode())
                        .setAadhaarMd5(MD5.md5(aadhaarNo))
                        .setMobileMd5(md5Mobile);
                String bizData = JSONObject.toJSONString(collisionDataRequest);

                LOGGER.info("== 撞库判断判断 ==");
                OpenApiResponse result = null;
                try {
                    result = CallHttpService.callMerchantMethod(productCategory.getMerchantDoaminUrl(), productCategory.getMerchantPublicKey(), "checkUser", productCategory.getMerchantCode(), bizData);
                } catch (Exception e) {
                    LOGGER.error("== 撞库判断判断 ==", e);
                    return false;
                }
                if (result != null) {
                    LOGGER.info("== 撞库判断判断 res==,res:{}", JsonStream.serialize(result));
                    CollisionDataVO collisionDataVO = new CollisionDataVO();
                    collisionDataVO.setMobile(mobile);
                    collisionDataVO.setMd5mobile(md5Mobile);
                    if (result.getCode() == BasicErrorCodeEnum.OPEN_API_SUCCESS.getCode()) {
                        LOGGER.info("== 撞库判断判断  pass ==");
                        collisionDataVO.setResult(CollisionResultEnm.PASS.getCode());
                    } else {
                        LOGGER.info("== 撞库判断判断  reject ==");
                        collisionDataVO.setResult(CollisionResultEnm.REJECT.getCode());
                        collisionPass = false;
                    }

                    try {
                        LOGGER.info("==aaa==");
                        UserOpenBlackListRequest request = new UserOpenBlackListRequest();
                        request.setOrgId(productCategory.getMerchantCode());
                        request.setMd5Mobile(md5Mobile);
                        request.setResult(JSONObject.toJSONString(result));
                        request.setRejectReason(result.getMessage());
                        request.setPackageName(packageName);
                        request.setIsOlder(0);
                        apiUserCenterService.saveOpenBlackHistory(request);
                        LOGGER.info("==aaa==,a:{},b:{},c:{},e:{}", JSONObject.toJSONString(collisionDataVO), DateUtil.getSecondsNextEarlyMorning(), mobile, productCategory.getMerchantCode());
                        redisClient.set(RedisKeyConsts.COLLISION_DATA_KEY, JSONObject.toJSONString(collisionDataVO), DateUtil.getSecondsNextEarlyMorning(), mobile, productCategory.getMerchantCode());
                        LOGGER.info("=== 撞库结果:{},productCategory:{}", JSONObject.toJSONString(collisionDataVO), productCategory.getCode());
                    } catch (Exception e) {
                        LOGGER.error("==撞库结果异常===", e);
                    }

                }
            }
//        } else {
//            CollisionDataVO collisionDataVO = JSONObject.parseObject(redisClient.get(RedisKeyConsts.COLLISION_DATA_KEY, mobile, productCategory.getMerchantCode()), CollisionDataVO.class);
//            if (collisionDataVO.getResult().equals(CollisionResultEnm.REJECT.getCode())) {
//                collisionPass = false;
//            }
//            LOGGER.info("=== 缓存中的撞库结果:{},productCategory:{}", JSONObject.toJSONString(collisionDataVO), productCategory.getCode());
//        }

        if (!collisionPass) {//撞库未通过
            quotaFull = true;
        }
        LOGGER.info("=== 综合额度 quotaFull:{}, mobile:{}, merchantCode:{} ====", quotaFull, mobile, productCategory.getMerchantCode());
        return quotaFull;
    }

    /**
     * 类目详情
     *
     * @param merchantCode
     * @return
     */
    public ProductDetailVO getProductDetailInfo(String merchantCode) {
        String mobile = RequestLocalInfo.getCurrentUser().getMobile();
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        ProductDetailVO productDetailVO = new ProductDetailVO();
        Response<List<ProductCategory>> response = productFacade.getProductCategoriesByMerchantCode(merchantCode);

        ProductCategory productCategory = response.getData().get(0);
        boolean quotaFull = this.currentMerchantQuotaFull(userCode, mobile, productCategory);
        productDetailVO.setPermitApply(!quotaFull);
        productDetailVO.setButtonMsg(quotaFull ? "Loan Quota has been used up today." : "NEXT");
        productDetailVO.setCategoryName(productCategory.getName())
                .setCategoryLogo(productCategory.getLogo())
                .setCategoryDesc(productCategory.getCategoryDesc())
                .setCategoryApplicationRatio(quotaFull ? 100 : productCategory.getApplyRate())
                .setReminderTips(quotaFull ? "Loan Quota has been used up today." : apolloConfigUtil.getProductDetailTips())
                .setMerchantCode(merchantCode);

        String extraInfo = productCategory.getExtraInfo();
        if (!StringUtils.isEmpty(extraInfo)) {
            Any extraInfoJson = JsonIterator.deserialize(extraInfo);
            Any developer_name = extraInfoJson.get("developer_name");
            if (developer_name != null) {
                productDetailVO.setCompanyName(developer_name.toString());
            }
            Any official_web_url = extraInfoJson.get("official_web_url");
            if (official_web_url != null) {
                productDetailVO.setCompanyUrl(official_web_url.toString());
            }

        }

        productDetailVO.setBorrowCashList(this.getProductByMerchantCode(merchantCode));
        userEventTrackService.e_app_open_create_order_page();
        return productDetailVO;
    }

    /**
     * 通过商户code获取产品列表
     *
     * @param merchantCode
     * @return
     */
    public List<BorrowCashVO> getProductByMerchantCode(String merchantCode) {
        //审核账号
        String mobile = RequestLocalInfo.getCurrentUser().getMobile();
        List<BorrowCashVO> borrowCash = Lists.newArrayList();
        if (apolloConfigUtil.auditMobiles().contains(mobile)) {
            List<BorrowCashPeriodVO> borrowCashPeriods = Lists.newArrayList();
            BorrowCashPeriodVO borrowCashPeriodVO = new BorrowCashPeriodVO()
                    .setLocked(false)
                    .setProductCode(AuditProductEnum.PRODUCT_90_DAYS.getProductCode())
                    .setDuration(AuditProductEnum.PRODUCT_90_DAYS.getDays().toString());
            borrowCashPeriods.add(borrowCashPeriodVO);
            BorrowCashVO borrowCashVO = new BorrowCashVO()
                    .setLocked(false)
                    .setAmount(AuditProductEnum.PRODUCT_90_DAYS.getAmount())
                    .setBorrowCashPeriods(borrowCashPeriods);
            borrowCash.add(borrowCashVO);
            return borrowCash;
        }
        Response<List<ProductCategory>> productCategoriesByMerchantCode = productFacade.getProductCategoriesByMerchantCode(merchantCode);
        ProductCategory productCategory = productCategoriesByMerchantCode.getData().get(0);

        List<Product> productList = Lists.newArrayList();
        //拉取获取借款额度和期限
        PullAmountAndTermRequest pullAmountAndTermRequest = new PullAmountAndTermRequest();
        pullAmountAndTermRequest.setMobile(MD5.md5(mobile).toLowerCase());
        pullAmountAndTermRequest.setOrgId(merchantCode);
        pullAmountAndTermRequest.setProductId(merchantCode);

        String bizData = JSONObject.toJSONString(pullAmountAndTermRequest);
        Response<List<Product>> listResponse = productFacade.getProductByMerchantCode(merchantCode);
        List<Product> products = listResponse.getData();
        Product showProduct = products.stream().sorted(Comparator.comparing(Product::getPrincipalMoney)).findFirst().get();
        if (apolloConfigUtil.productDetailSyncSwitch()) {
            OpenApiResponse result = CallHttpService.callMerchantMethod(productCategory.getMerchantDoaminUrl(), productCategory.getMerchantPublicKey(), "/gupta.loan.amount", productCategory.getMerchantCode(), bizData);
            LOGGER.info("== 获取详情页的类目下的产品列表 ==,merchantCode:{},result:{}", merchantCode, result);
            if (result != null && result.getCode() == BasicErrorCodeEnum.OPEN_API_SUCCESS.getCode()) {
                PullAmountTermVO pullAmountTermVO = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), PullAmountTermVO.class);
                Response<Product> response = productFacade.getProductByMerchantCodeAndPrincipalMoneyAndPeriod(merchantCode, new BigDecimal(pullAmountTermVO.getLoanAmount()), Integer.valueOf(pullAmountTermVO.getLoanTerm()));
                if (response.getData() != null) {
                    showProduct = response.getData();
                }
                LOGGER.info("== 获取详情页的类目下的产品列表 ==,merchantCode:{},result:{},productList:{}", merchantCode, result, productList);
            }
        }
        productList.add(showProduct);
        Product product2 = new Product();
        Product product3 = new Product();
        BeanUtils.copyProperties(showProduct, product2);
        BeanUtils.copyProperties(showProduct, product3);

        product2.setActive(false).setPaybackPeriodLength(90).setPrincipalMoney((Double.parseDouble(showProduct.getPrincipalMoney())) * 2 + "");
        product3.setActive(false).setPaybackPeriodLength(180).setPrincipalMoney((Double.parseDouble(showProduct.getPrincipalMoney())) * 3 + "");
        productList.add(product2);
        productList.add(product3);
//        productList.add(showProduct.setActive(false).setPrincipalMoney((Integer.parseInt(showProduct.getPrincipalMoney()) + 2000) + ""));
//        productList.add(showProduct.setActive(false).setPrincipalMoney((Integer.valueOf(showProduct.getPrincipalMoney()) + 4000) + ""));


        if (CollectionUtils.isEmpty(productList)) {
            return ListUtils.EMPTY_LIST;
        }
        Map<Integer, BorrowCashVO> cashMap = new HashMap<>();
        List<String> productCodeList = new ArrayList<>();
        for (Product product : productList) {
            productCodeList.add(product.getCode());
        }

//        LOGGER.info("== 获取详情页的类目下的产品列表 ==,merchantCode:{},result:{},productList:{},productCodeList:{}", merchantCode, result, productList, productCodeList);
        Response<Map<String, OfferResponse>> mapResponse = quoteQueryService.quoteDetailMap(productCodeList);
        Map<String, OfferResponse> offerMap = mapResponse.getData();
        if (offerMap == null || offerMap.isEmpty()) {
            return ListUtils.EMPTY_LIST;
        }
        for (Product product : productList) {
            PaybackPeriodUnitEnum paybackPeriodUnitEnum = PaybackPeriodUnitEnum.getByCode(product.getProductCategory().getPaybackPeriodUnit());
            //短期取到账金额 分期取借款金额
            int amount = new BigDecimal(product.getPrincipalMoney()).intValue();
            if (paybackPeriodUnitEnum == PaybackPeriodUnitEnum.MONTH) {
                amount = new BigDecimal(product.getPrincipalMoney()).intValue();
            }
            BorrowCashVO borrowCashVO = cashMap.get(amount);
            borrowCashVO = borrowCashVO == null ? new BorrowCashVO() : borrowCashVO;
            List<BorrowCashPeriodVO> periodList = borrowCashVO.getBorrowCashPeriods() == null ? Lists.newArrayList() : borrowCashVO.getBorrowCashPeriods();
            String unitName = paybackPeriodUnitEnum == PaybackPeriodUnitEnum.MONTH ? "期" : paybackPeriodUnitEnum.getName();
            BorrowCashPeriodVO borrowCashPeriodVO;
            if (paybackPeriodUnitEnum == PaybackPeriodUnitEnum.MONTH) {
                borrowCashPeriodVO = new BorrowCashPeriodVO(product.getTotalPaybackPeriodCount() + unitName);
            } else {
                borrowCashPeriodVO = new BorrowCashPeriodVO(product.getPaybackPeriodLength() + " Days(min)");
            }
            borrowCashPeriodVO.setProductCode(product.getCode());
            Response<OfferResponse> offerResponse = quoteQueryService.quoteDetail(product.getCode());
            OfferResponse offer = offerResponse.getData();
            List<OrderFieldDetail> fieldDetailList = convert2OtherInfo(offer, product.getProductCategory().getCode());
            borrowCashPeriodVO.setOtherInfo(fieldDetailList);
            if (offerMap.containsKey(product.getCode())) {
                borrowCashPeriodVO.setLocked(!product.getActive());
                periodList.add(borrowCashPeriodVO);
                borrowCashVO.setBorrowCashPeriods(periodList);
                borrowCashVO.setAmount(amount);
                borrowCashVO.setLocked(!product.getActive());
                cashMap.put(amount, borrowCashVO);
            }
        }
        return sortCashList(new ArrayList<>(cashMap.values()));
    }

    public List<OrderFieldDetail> convert2OtherInfo(OfferResponse offerResponse, String productCategory) {

        OrderFieldDetail interest = new OrderFieldDetail("Interest", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getTotalInterestFee())), null));
        OrderFieldDetail serviceFees = new OrderFieldDetail("Service Fees", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getTotalServiceFee())), null));
        OrderFieldDetail gst = new OrderFieldDetail("GST", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getGstCharge())), null));
        OrderFieldDetail receiveAmount = new OrderFieldDetail("Amount You Get", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getReceivedTotalCapital())), null));
        OrderFieldDetail repaymentAmount = new OrderFieldDetail("Amount You Repay", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getPeriodRepaymentCapital())), null));
        List<OrderFieldDetail> orderFieldDetails = Lists.newArrayList();
//
//        boolean isGpVersion = RequestLocalInfo.getRequestBasicInfo().getVersionCode() >= apolloConfigUtil.getDefaultOnlineVersionCode();
        boolean isGpVersion = apolloConfigUtil.getGPfeescontrollecategories().contains(productCategory);
        if (isGpVersion) {
            String interestContent = DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getTotalInterestFee()));
            interest = new OrderFieldDetail("Interest", "1", new OrderFieldDetail.SchemeURL("₹ " + interestContent + "(" + offerResponse.getBorrowTotalCapital() + "x" + offerResponse.getBorrowRatio() + "x" + offerResponse.getPeriodLength() + "/365)", null));

            serviceFees = new OrderFieldDetail("Service Fees", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(0)), null));
            gst = new OrderFieldDetail("GST", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(0)), null));
            receiveAmount = new OrderFieldDetail("Amount You Get", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getBorrowTotalCapital())), null));
            repaymentAmount = new OrderFieldDetail("Amount You Repay", "1", new OrderFieldDetail.SchemeURL("₹ " + DecimalUtils.formatDecimal(new BigDecimal(offerResponse.getBorrowTotalCapital()).add(new BigDecimal(offerResponse.getTotalInterestFee()))), null));
        }

        orderFieldDetails.add(interest);
        orderFieldDetails.add(serviceFees);
        orderFieldDetails.add(gst);
        orderFieldDetails.add(receiveAmount);
        orderFieldDetails.add(repaymentAmount);
        return orderFieldDetails;
    }

    /**
     * 排序BorrowCashVOList
     *
     * @param borrowCashVOList
     * @return
     */
    public List<BorrowCashVO> sortCashList(List<BorrowCashVO> borrowCashVOList) {
        if (CollectionUtils.isEmpty(borrowCashVOList)) {
            return ListUtils.EMPTY_LIST;
        }
        //只展示最高额度
//        BorrowCashVO borrowCashVO = borrowCashVOList.stream().reduce((first, second) -> second).orElse(null);
        //对金额进行升序排序
        Collections.sort(borrowCashVOList, (o1, o2) -> {
            int diff = o1.getAmount() - o2.getAmount();
            if (diff > 0) {
                return 1;
            } else if (diff < 0) {
                return -1;
            }
            return 0;
        });


        boolean isGpVersion = RequestLocalInfo.getRequestBasicInfo().getVersionCode() >= apolloConfigUtil.getDefaultOnlineVersionCode();
        if (isGpVersion) {
            borrowCashVOList.get(0).getBorrowCashPeriods().add(new BorrowCashPeriodVO("180 Days(max)").setLocked(true));
        }
//        if (borrowCashVO != null) {
//            borrowCashVOList = Lists.newArrayList(borrowCashVO);
//        }

        return borrowCashVOList;
    }

    /**
     * 根据用户等级、新老客 获取产品
     *
     * @param productCategory
     * @param userLevel
     * @param isNewUser
     * @param registerDate
     * @return
     */
    public Product getProductByCategoryCodeAndLevel(String productCategory, int userLevel, boolean isNewUser, Date registerDate) {
        List<Product> productList = getProductListByCategoryCode(productCategory);
        for (int i = 0; i < productList.size(); i++) {
            Product product = productList.get(i);
            if (product.getRiskLevel() > userLevel) {
                productList.remove(i);
                i--;
            } else if (product.getConfig() != null) {
                //注册时间小于起始时间 或 大于等于结束时间 移除
                if (StringUtils.isNotEmpty(product.getConfig().getRegisterStartDate())
                        && registerDate.getTime() < DateUtil.getDate(product.getConfig().getRegisterStartDate(), "yyyy-MM-dd").getTime()) {
                    productList.remove(i);
                    i--;
                }
                if (StringUtils.isNotEmpty(product.getConfig().getRegisterEndDate())
                        && registerDate.getTime() >= DateUtil.getDate(product.getConfig().getRegisterEndDate(), "yyyy-MM-dd").getTime()) {
                    productList.remove(i);
                    i--;
                }
            }
        }
        if (org.apache.commons.collections.CollectionUtils.isEmpty(productList)) {
            throw new ApplicationException("Quota evaluation failed");
        }
        return productList.get(productList.size() - 1);
    }

    /**
     * 获取上架的产品按照等级从小到大 金额从小到大排序 期限从小到大
     */
    private List<Product> getProductListByCategoryCode(String productCategory) {
        Response<List<Product>> productResponse = productFacade.getActiveProductList(productCategory, false);
        if (productResponse == null || !productResponse.isSuccess()) {
            throw new ApplicationException(productResponse == null ? "获取产品信息失败" : productResponse.getMsg());
        }
        List<Product> productList = productResponse.getData();
        for (int i = 0; i < productList.size(); i++) {
            Product product = productList.get(i);
            if (!"1".equals(product.getShowFlag())) {
                productList.remove(i);
                i--;
            }
        }
        //按照等级从小到大 金额从小到大排序 期限从小到大
        productList.sort((o1, o2) -> {
            if (o1.getRiskLevel() < o2.getRiskLevel()) {
                return -1;
            } else if (o1.getRiskLevel() > o2.getRiskLevel()) {
                return 1;
            } else {
                if (Double.parseDouble(o1.getPrincipalMoney()) < Double.parseDouble(o2.getPrincipalMoney())) {
                    return -1;
                } else if (Double.parseDouble(o1.getPrincipalMoney()) > Double.parseDouble(o2.getPrincipalMoney())) {
                    return 1;
                } else {
                    return Integer.compare(o1.getTotalPaybackPeriodCount() * o1.getPaybackPeriodLength(), o2.getTotalPaybackPeriodCount() * o2.getPaybackPeriodLength());
                }
            }
        });

        return productList;
    }

    /**
     * 授信首页
     *
     * @return
     */
    public CreditHomeVO creditHome() {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        String mobile = RequestLocalInfo.getCurrentUser().getMobile();
        String jumpUrl;
        String packageName = RequestLocalInfo.getRequestBasicInfo().getPackageName();
        UserAuthStatusRO userAuthStatus = apiUserService.getUserAuthStatus(userCode);
        if (PackageNameEnum.CREDFOX.getPackageName().equalsIgnoreCase(packageName)) {
            boolean panComplete = userAuthStatus.getPanStatus() == UserAuthStatusEnum.SUCCESS.getCode();
            boolean bankComplete = userAuthStatus.getBankStatus() == UserAuthStatusEnum.SUCCESS.getCode();
            boolean kycComplete = apiUserService.kycActionComplete(userAuthStatus);
            boolean basicComplete = userAuthStatus.getBaseInfoStatus() == UserAuthStatusEnum.SUCCESS.getCode() && userAuthStatus.getEmailStatus() == UserAuthStatusEnum.SUCCESS.getCode();
            boolean contactComplete = userAuthStatus.getBaseEmergencyStatus() == UserAuthStatusEnum.SUCCESS.getCode();
            boolean workComplete = userAuthStatus.getBaseWorkStatus() == UserAuthStatusEnum.SUCCESS.getCode();
            boolean baseInfoComplete = basicComplete && contactComplete && workComplete;
            boolean isCredit = apiUserCenterService.isCreditComplete(userCode);
            if (!basicComplete) {
                jumpUrl = JumpRouterEnum.PERSONAL_INFO.getJumpUrl();
            } else if (basicComplete && !contactComplete) {
                jumpUrl = JumpRouterEnum.PERSONAL_INFO.getJumpUrl();
            } else if (basicComplete && contactComplete && !workComplete) {
                jumpUrl = JumpRouterEnum.PERSONAL_INFO_EMPLOYEE.getJumpUrl();
            } else if (baseInfoComplete && !kycComplete) {
                jumpUrl = JumpRouterEnum.KYC_DOCUMENTS_AADHAAR.getJumpUrl();
            } else if (baseInfoComplete && kycComplete && !panComplete) {
                jumpUrl = JumpRouterEnum.KYC_DOCUMENTS_AADHAAR.getJumpUrl();
            } else if (baseInfoComplete && kycComplete && panComplete && !bankComplete) {
                jumpUrl = JumpRouterEnum.PERSONAL_INFO_BANK.getJumpUrl();
            } else if (baseInfoComplete && kycComplete && panComplete && bankComplete && !isCredit) {
                jumpUrl = JumpRouterEnum.CREDIT_AUDIT.getJumpUrl();
            } else {
                jumpUrl = JumpRouterEnum.HOME.getJumpUrl();
            }
        } else {
            //判断个人资料状态
            boolean profileFinished = apiUserService.allActionComplete(userCode);
            jumpUrl = apiUserService.getJumpUrl(profileFinished, userCode);
        }

        CreditHomeVO creditHomeVO = new CreditHomeVO();
        creditHomeVO.setHasUnreadMessage(false);
        creditHomeVO.setMaxAmount("₹" + apolloConfigUtil.getCreditAmount());
        creditHomeVO.setJumpUrl(jumpUrl);
        creditHomeVO.setNeedALGO360Verify(false);
        creditHomeVO.setPermissionsInfo(null);
        if (!apolloConfigUtil.permitOrder() && !apolloConfigUtil.permitOrderUserMobile().contains(mobile)) {
            creditHomeVO.setTips(apolloConfigUtil.notPermitOrderTips());
            creditHomeVO.setEnableJump(false);
        }
        //新客申请开关
        if (!apolloConfigUtil.permitOrderForNewUser(PackageNameEnum.getAppSummary(packageName))
                && apiUserService.isNewUser(userCode) && !apolloConfigUtil.permitOrderUserMobile().contains(mobile)) {
            creditHomeVO.setTips(apolloConfigUtil.notPermitOrderTips());
            creditHomeVO.setEnableJump(false);
        }

        if (apolloConfigUtil.auditMobiles().contains(mobile)) {
            creditHomeVO.setEnableJump(true);
            creditHomeVO.setTips("");
        }
        return creditHomeVO;
    }

}
